package icu.d4peng.basic.knife4j;

import icu.d4peng.basic.knife4j.properties.Knife4jProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import com.github.xiaoymin.knife4j.extend.filter.basic.ServletSecurityBasicAuthFilter;
import icu.d4peng.basic.knife4j.extension.Knife4jOpenApiCustomizer;
import icu.d4peng.basic.knife4j.extension.Knife4jOperationCustomizer;
import icu.d4peng.basic.knife4j.filter.ProductionSecurityFilter;

/**
 * @author d4peng d4peng@qq.com
 * @date 2023-11-25 19:42:44
 */
@AutoConfiguration
@EnableConfigurationProperties({ Knife4jProperties.class })
@ConditionalOnProperty(prefix = Knife4jProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
public class Knife4jAutoConfiguration {

	private static final Logger LOGGER = LoggerFactory.getLogger(Knife4jAutoConfiguration.class);

	/**
	 * 增强自定义配置
	 *
	 */
	@Bean
	@ConditionalOnMissingBean
	public Knife4jOpenApiCustomizer knife4jOpenApiCustomizer(Knife4jProperties knife4jProperties) {
		LOGGER.debug("Register Knife4jOpenApiCustomizer");
		return new Knife4jOpenApiCustomizer(knife4jProperties);
	}

	@Bean
	@ConditionalOnMissingBean
	public Knife4jOperationCustomizer knife4jOperationCustomizer() {
		return new Knife4jOperationCustomizer();
	}

	/**
	 * 配置Cors
	 *
	 */
	@Bean("knife4jCorsFilter")
	@ConditionalOnMissingBean(CorsFilter.class)
	@ConditionalOnProperty(prefix = Knife4jProperties.PREFIX, name = "cors", havingValue = "true",
			matchIfMissing = true)
	public CorsFilter corsFilter() {
		LOGGER.info("init CorsFilter...");
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		CorsConfiguration corsConfiguration = new CorsConfiguration();
		corsConfiguration.setAllowCredentials(true);
		corsConfiguration.addAllowedOrigin("*");
		corsConfiguration.addAllowedHeader("*");
		corsConfiguration.addAllowedMethod("*");
		corsConfiguration.setMaxAge(10000L);
		// 匹配所有API
		source.registerCorsConfiguration("/**", corsConfiguration);
		CorsFilter corsFilter = new CorsFilter(source);
		return corsFilter;
	}

	/**
	 * Security with Basic Http
	 *
	 */
	@Bean
	@ConditionalOnMissingBean(ServletSecurityBasicAuthFilter.class)
	@ConditionalOnProperty(prefix = Knife4jProperties.PREFIX + ".basic", name = "enabled", havingValue = "true",
			matchIfMissing = true)
	public ServletSecurityBasicAuthFilter securityBasicAuthFilter(Knife4jProperties knife4jProperties) {
		ServletSecurityBasicAuthFilter authFilter = new ServletSecurityBasicAuthFilter();
		authFilter.setEnableBasicAuth(knife4jProperties.getBasic().isEnabled());
		authFilter.setUserName(knife4jProperties.getBasic().getUsername());
		authFilter.setPassword(knife4jProperties.getBasic().getPassword());
		authFilter.addRule(knife4jProperties.getBasic().getInclude());
		return authFilter;
	}

	@Bean
	@ConditionalOnMissingBean(ProductionSecurityFilter.class)
	@ConditionalOnProperty(prefix = Knife4jProperties.PREFIX, name = "production", havingValue = "true",
			matchIfMissing = true)
	public ProductionSecurityFilter productionSecurityFilter(Knife4jProperties knife4jProperties) {
		return new ProductionSecurityFilter(knife4jProperties.isProduction());
	}

}
